﻿using CCWin;
using ERP_SaaS_WinForm.物料管理.Material;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace ERP_SaaS_WinForm.物料管理
{
    public partial class PinkingForm : CCSkinMain
    {  
        // 存储选中的物料列表
        private List<MaterialPickDto> selectedMaterials = new List<MaterialPickDto>();
        public PinkingForm()
        {
            InitializeComponent();
            this.Load += PinkingForm_Load;
            InitializeMaterialDataGridView();
            InitializePinkingInfoDataGridView(); // 添加这行
            InitializeOutboundGrid();
            // 为移除按钮添加事件处理
            if (btnDelPinking != null)
            {
                btnDelPinking.Click += btnDelPinking_Click;
            }
            if (btnAddPinking != null)
            {
                btnAddPinking.Click -= btnAddPinking_Click; // 防止重复绑定
                btnAddPinking.Click += btnAddPinking_Click;
            }
        }
        private void btnMaterialInfo_Click(object sender, EventArgs e)
        {
            try
            {
                // 创建并显示选择物料窗体
                SelectMaterialForm selectMaterialForm = new SelectMaterialForm();
                selectMaterialForm.AllowMultipleSelection = true; // 允许多选
                
                // 显示对话框并获取结果
                if (selectMaterialForm.ShowDialog() == DialogResult.OK)
                {
                    // 获取选中的物料
                    var newMaterials = selectMaterialForm.SelectedMaterials;
                    if (newMaterials != null && newMaterials.Count > 0)
                    {
                        // 将新选中的物料添加到列表中
                        foreach (var material in newMaterials)
                        {
                            // 检查是否已经存在相同的物料
                            if (!selectedMaterials.Any(m => m.materialCode == material.materialCode))
                            {
                                // 使用新的MaterialPickDto类创建物料项
                                var materialItem = MaterialPickDto.FromMaterialInfo(material);
                                selectedMaterials.Add(materialItem);
                            }
                        }
                        
                        // 刷新数据网格显示
                        RefreshMaterialDataGridView();
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show($"打开选择物料页面失败: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
        /// <summary>
        /// 初始化物料数据网格
        /// </summary>
        private void InitializeMaterialDataGridView()
        {
            if (dgvShowPinking != null)
            {
                dgvShowPinking.AutoGenerateColumns = false;
                dgvShowPinking.AllowUserToAddRows = false;
                dgvShowPinking.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
                dgvShowPinking.MultiSelect = false;
                
                // 设置列的数据绑定
                if (dgvShowPinking.Columns.Count >= 7)
                {
                    dgvShowPinking.Columns[0].DataPropertyName = "materialName";      // 物料名称
                    dgvShowPinking.Columns[1].DataPropertyName = "materialCode";      // 物料编号
                    dgvShowPinking.Columns[2].DataPropertyName = "specification";     // 规格型号
                    dgvShowPinking.Columns[3].DataPropertyName = "unit";              // 单位
                    dgvShowPinking.Columns[4].DataPropertyName = "currentInventory";  // 当前库存
                    dgvShowPinking.Columns[5].DataPropertyName = "pickQuantity";      // 领用数量
                    dgvShowPinking.Columns[6].DataPropertyName = "warehouseCode";     // 仓库编号
                    
                    // 设置领用数量列为可编辑
                    dgvShowPinking.Columns[5].ReadOnly = false;
                    
                    // 为领用数量列添加验证事件
                    dgvShowPinking.CellValidating += DgvShowPinking_CellValidating;
                    dgvShowPinking.CellEndEdit += DgvShowPinking_CellEndEdit;
                }
            }
        }
        /// <summary>
        /// 初始化领料信息数据网格
        /// </summary>
        private void InitializePinkingInfoDataGridView()
        {
            if (dgvPinkingInfo != null)
            {         
                // 添加操作列
                DataGridViewButtonColumn operationColumn = new DataGridViewButtonColumn();
                operationColumn.HeaderText = "出库操作";
                operationColumn.Name = "Operation";
                operationColumn.Text = "出库";
                operationColumn.UseColumnTextForButtonValue = true;
                operationColumn.Width = 50;
                dgvPinkingInfo.Columns.Add(operationColumn);
                
                // 添加单元格点击事件
                dgvPinkingInfo.CellClick += DgvPinkingInfo_CellClick;
            }
        }
        /// <summary>
        /// 领料信息数据网格单元格点击事件
        /// </summary>
        private void DgvPinkingInfo_CellClick(object sender, DataGridViewCellEventArgs e)
        {
            if (e.RowIndex >= 0 && e.ColumnIndex == dgvPinkingInfo.Columns["Operation"].Index)
            {
                int rowIndex = e.RowIndex;

                // 从绑定对象读取 OutboundId 与出库状态
                var dto = dgvPinkingInfo.Rows[rowIndex].DataBoundItem as PinkingInfoDto;
                if (dto == null) return;

                int id = dto.outboundId;
                bool pickState = dto.pickState;

                if (pickState)
                {
                    MessageBox.Show("该领料单已经出库，不能重复操作！", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    return;
                }

                if (MessageBox.Show("确定要出库这个领料单吗？", "确认出库", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
                {
                    _ = OutboundMaterial(id, rowIndex);
                }
            }
        }
        /// <summary>
        /// 出库操作
        /// </summary>
        private async Task OutboundMaterial(int id, int rowIndex)
        {
            try
            {
                string url = $"http://localhost:5128/api/Pinking/UpdStateMaterialRequisition?OutboundId={id}";
                using (HttpClient client = new HttpClient())
                {
                    HttpResponseMessage response = await client.GetAsync(url);
                    if (response.IsSuccessStatusCode)
                    {
                        string jsonResponse = await response.Content.ReadAsStringAsync();
                        MessageBox.Show("出库操作成功！", "成功", MessageBoxButtons.OK, MessageBoxIcon.Information);
                        // 刷新数据
                        await BindPickingAsync();
                    }
                    else
                    {
                        MessageBox.Show($"出库操作失败: {response.StatusCode}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show($"出库操作异常: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        /// <summary>
        /// 单元格验证事件 - 验证输入的数量是否有效
        /// </summary>
        private void DgvShowPinking_CellValidating(object sender, DataGridViewCellValidatingEventArgs e)
        {
            // 只验证领用数量列（第5列）
            if (e.ColumnIndex == 5)
            {
                string inputValue = e.FormattedValue.ToString();
                
                // 检查是否为空
                if (string.IsNullOrWhiteSpace(inputValue))
                {
                    e.Cancel = true;
                    MessageBox.Show("领用数量不能为空！", "验证错误", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    return;
                }
                
                // 检查是否为有效数字
                if (!decimal.TryParse(inputValue, out decimal quantity))
                {
                    e.Cancel = true;
                    MessageBox.Show("请输入有效的数量！", "验证错误", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    return;
                }
                
                // 检查数量是否大于0
                if (quantity <= 0)
                {
                    e.Cancel = true;
                    MessageBox.Show("领用数量必须大于0！", "验证错误", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    return;
                }
                
                // 检查数量是否超过当前库存
                if (dgvShowPinking.Rows[e.RowIndex].Cells[4].Value != null)
                {
                    if (decimal.TryParse(dgvShowPinking.Rows[e.RowIndex].Cells[4].Value.ToString(), out decimal currentInventory))
                    {
                        if (quantity > currentInventory)
                        {
                            e.Cancel = true;
                            MessageBox.Show($"领用数量不能超过当前库存({currentInventory})！", "验证错误", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                            return;
                        }
                    }
                }
            }
        }
        /// <summary>
        /// 单元格编辑完成事件 - 更新数据源
        /// </summary>
        private void DgvShowPinking_CellEndEdit(object sender, DataGridViewCellEventArgs e)
        {
            // 只处理领用数量列（第5列）
            if (e.ColumnIndex == 5 && e.RowIndex >= 0 && e.RowIndex < selectedMaterials.Count)
            {
                if (int.TryParse(dgvShowPinking.Rows[e.RowIndex].Cells[e.ColumnIndex].Value?.ToString(), out int newQuantity))
                {
                    // 更新数据源中的数量
                    selectedMaterials[e.RowIndex].pickQuantity = newQuantity;
                }
            }
        }
        /// <summary>
        /// 刷新物料数据网格显示
        /// </summary>
        private void RefreshMaterialDataGridView()
        {
            if (dgvShowPinking != null)
            {
                dgvShowPinking.DataSource = null;
                dgvShowPinking.DataSource = selectedMaterials;
            }
        }
        /// <summary>
        /// 移除选中的物料
        /// </summary>
        private void RemoveSelectedMaterial()
        {
            if (dgvShowPinking != null && dgvShowPinking.CurrentRow != null)
            {
                int currentRowIndex = dgvShowPinking.CurrentRow.Index;
                if (currentRowIndex >= 0 && currentRowIndex < selectedMaterials.Count)
                {
                    selectedMaterials.RemoveAt(currentRowIndex);
                    RefreshMaterialDataGridView();
                }
            }
        }
        /// <summary>
        /// 移除按钮点击事件
        /// </summary>
        private void btnDelPinking_Click(object sender, EventArgs e)
        {
            RemoveSelectedMaterial();
        }
        //领料单显示
        private async Task BindPickingAsync()
        {
            string baseUrl = "http://localhost:5128/api/Pinking/GetPinkingOrder";
            if (!string.IsNullOrEmpty(txtPinkingOrderCode.Text))
            {
                baseUrl += $"?PickFormCode={Uri.EscapeDataString(txtPinkingOrderCode.Text)}";
            }
            if (!string.IsNullOrEmpty(txtProductionOrdersCode.Text))
            {
                baseUrl += $"?Production={Uri.EscapeDataString(txtProductionOrdersCode.Text)}";
            }
            using (HttpClient client = new HttpClient())
            {
                try
                {
                    HttpResponseMessage response = await client.GetAsync(baseUrl);
                    response.EnsureSuccessStatusCode();
                    string jsonResponse = await response.Content.ReadAsStringAsync();
                    MaterialApiResponse<PinkingInfoDto> apiResponse = JsonConvert.DeserializeObject<MaterialApiResponse<PinkingInfoDto>>(jsonResponse);
                    if (apiResponse.code == 200)
                    {
                        dgvPinkingInfo.AutoGenerateColumns = false;
                        dgvPinkingInfo.DataSource = apiResponse.pageDatas;
                    }
                    else
                    {
                        MessageBox.Show($"查询失败{apiResponse?.message}");
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show($"请求失败: {ex.Message}");
                }
            }
        }
        private async void PinkingForm_Load(object sender, EventArgs e)
        {
            await BindPickingAsync();
        }
        private async void btnSearch_Click(object sender, EventArgs e)
        {
            await BindPickingAsync();
        }

        //新增领料单
        private async void btnAddPinking_Click(object sender, EventArgs e)
        {
            await CreateOutboundAsync();
        }
        private class CreateOutboundRequest
        {
            public string pickFormName { get; set; }
            public string pickFormCode { get; set; }
            public DateTime pickDate { get; set; }
            public string picker { get; set; }
            public string productionOrdersCode { get; set; }
            public string dispatchCode { get; set; }
            public List<PickItem> picks { get; set; }
        }
        private class PickItem
        {
            public int pickingId { get; set; } = 0;
            public string pickFormCode { get; set; }
            public string materialCode { get; set; }
            public int pickingQuantity { get; set; }
            public string warehouseCode { get; set; }
            public bool isDel { get; set; } = false;
        }
        private async Task CreateOutboundAsync()
        {
            if (selectedMaterials == null || selectedMaterials.Count == 0)
            {
                MessageBox.Show("请先添加物料！", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                return;
            }
            string pickFormCode = txtPickFormCode?.Text?.Trim();
            string pickFormName = txtPickFormName?.Text?.Trim();
            string pickerName = txtPicker?.Text?.Trim();
            string productionCode = txtProductionOrders?.Text?.Trim();
            string dispatch = txtDispatchCode?.Text?.Trim(); // 可按需填入派工编号

            if (string.IsNullOrWhiteSpace(pickFormCode) || string.IsNullOrWhiteSpace(pickFormName))
            {
                MessageBox.Show("请填写领料单编号和名称！", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }

            DateTime pickDate = DateTime.Now;
            if (!string.IsNullOrWhiteSpace(dtpPickDate?.Text) && DateTime.TryParse(dtpPickDate.Text, out var dt))
            {
                pickDate = dt;
            }

            var request = new CreateOutboundRequest
            {
                pickFormCode = pickFormCode,
                pickFormName = pickFormName,
                pickDate = pickDate,
                picker = pickerName,
                productionOrdersCode = productionCode,
                dispatchCode = dispatch,
                picks = selectedMaterials.Select(m => new PickItem
                {
                    pickFormCode = pickFormCode,
                    materialCode = m.materialCode,
                    pickingQuantity = m.pickQuantity,
                    warehouseCode = m.warehouseCode,
                    isDel = false
                }).ToList()
            };

            string url = "http://localhost:5128/api/Pinking/CreateOutboundRecord";
            string json = JsonConvert.SerializeObject(request);
            using (HttpClient client = new HttpClient())
            using (var content = new StringContent(json, Encoding.UTF8, "application/json"))
            {
                var response = await client.PostAsync(url, content);
                if (response.IsSuccessStatusCode)
                {
                    MessageBox.Show("新增领料单成功！", "成功", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    selectedMaterials.Clear();
                    RefreshMaterialDataGridView();
                    await BindPickingAsync();
                    tabShowPinkOrder.Show();
                }
                else
                {
                    string body = await response.Content.ReadAsStringAsync();
                    MessageBox.Show($"新增失败: {response.StatusCode} {body}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
        }

        /// <summary>
        /// 初始化领料单列表，添加删除操作列
        /// </summary>
        private void InitializeOutboundGrid()
        {
            if (dgvPinkingInfo == null) return;
            // 只添加一次
            if (!dgvPinkingInfo.Columns.Contains("Delete"))
            {
                var col = new DataGridViewButtonColumn
                {
                    Name = "Delete",
                    HeaderText = "删除",
                    Text = "删除",
                    UseColumnTextForButtonValue = true,
                    Width = 70
                };
                dgvPinkingInfo.Columns.Add(col);
            }
            // 绑定单击事件
            dgvPinkingInfo.CellClick -= dgvPinkingInfo_CellClick;
            dgvPinkingInfo.CellClick += dgvPinkingInfo_CellClick;
        }

        /// <summary>
        /// 处理删除按钮点击
        /// </summary>
        private async void dgvPinkingInfo_CellClick(object sender, DataGridViewCellEventArgs e)
        {
            if (e.RowIndex < 0) return;
            if (!dgvPinkingInfo.Columns.Contains("Delete")) return;
            if (e.ColumnIndex != dgvPinkingInfo.Columns["Delete"].Index) return;

            var dto = dgvPinkingInfo.Rows[e.RowIndex].DataBoundItem as PinkingInfoDto;
            if (dto == null) return;
            // 已出库不可删除
            if (dto.pickState)
            {
                MessageBox.Show("该领料单已经出库，不能删除！", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                return;
            }
            int id = dto.outboundId;
            if (id <= 0)
            {
                MessageBox.Show("未获取到要删除的记录ID(OutboundId)");
                return;
            }

            if (MessageBox.Show("确定要删除该领料单记录吗？", "确认删除", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
            {
                await DeleteOutboundAsync(id);
            }
        }

        /// <summary>
        /// 调用后端删除接口
        /// </summary>
        private async Task DeleteOutboundAsync(int id)
        {
            string url = $"http://localhost:5128/api/Pinking/DelOutboundRecord?Id={id}";
            using (HttpClient client = new HttpClient())
            {
                try
                {
                    var resp = await client.GetAsync(url);
                    if (resp.IsSuccessStatusCode)
                    {
                        MessageBox.Show("删除成功！", "成功", MessageBoxButtons.OK, MessageBoxIcon.Information);
                        await BindPickingAsync();
                    }
                    else
                    {
                        string body = await resp.Content.ReadAsStringAsync();
                        MessageBox.Show($"删除失败: {resp.StatusCode} {body}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show($"删除发生异常: {ex.Message}");
                }
            }
        }
    }
}
